using System;
using System.Collections.Generic;
using System.Reflection;
using System.Linq;
using System.Text;

/**
*@file       gwMessageTab.cs
*@brief      process message
*
*@author     graywind
*@version    1.0.0.0
*@data       2012/01/04
*/

public interface IGetMessageProc<MessageProc>
{
    MessageProc MsgProc { get; }
}

public class RegisterMessageProc<ProcType, MessageProc> : IGetMessageProc<MessageProc>
{
    private MessageProc m_msgProc;

    public RegisterMessageProc(MessageProc msgProc)
    {
        m_msgProc = msgProc;
    }

    public MessageProc MsgProc
    {
        get
        {
            return m_msgProc;
        }
    }
}

[System.AttributeUsage(System.AttributeTargets.Field)]
class MessageProcTypeAttribute : System.Attribute
{
    public int MessageType;
    public MessageProcTypeAttribute(int message_type)
    {
        MessageType = message_type;
    }
}

public partial class MessageProcTypes<ProcType, MessageProc>
{
    public static System.Collections.Generic.Dictionary<int, MessageProc> ProcRegister = new Dictionary<int, MessageProc>();

    static MessageProcTypes()
    {
        Type type = typeof(MessageProcTypes<ProcType, MessageProc>);
        foreach (FieldInfo fi in type.GetFields())
        {
            MessageProcTypeAttribute attr = Attribute.GetCustomAttribute(fi, typeof(MessageProcTypeAttribute)) as MessageProcTypeAttribute;
            if (attr == null)
                continue;

            ProcRegister.Add(attr.MessageType, ((IGetMessageProc<MessageProc>)fi.GetValue(null)).MsgProc);
        }
    }
}

//ProcType class must implement this interface
public interface IGetMaxTypeCount
{
    int GetMaxTypeCount();
}

//message tab
public class gwMessageTab<ProcType, MessageProc> where ProcType : IGetMaxTypeCount, new()
{
    public static MessageProc[] FuncPtrArray;

    static gwMessageTab()
    {
        ProcType pt = new ProcType();
        FuncPtrArray = new MessageProc[pt.GetMaxTypeCount()];
        foreach (int key in MessageProcTypes<ProcType, MessageProc>.ProcRegister.Keys)
        {
            FuncPtrArray[key] = MessageProcTypes<ProcType, MessageProc>.ProcRegister[key];
        }
    }
}